package com.ts.api.module.match.plan.internal.distribute.strategy;

import com.gitee.apanlh.exp.ParamParserException;
import com.gitee.apanlh.util.base.BigDecimalUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.productflow.ProductApplyFlowStatusEnum;
import com.ts.api.common.redis.ApiMatchRedisKey;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMd5DataExchange;
import com.ts.api.module.api.convert.platform.handler.ApiPlatformPhoneMd5ConvertHandler;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistribute;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeField;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributePhoneMd5Field;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributePost;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeResult;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeUserRequest;
import com.ts.api.module.match.plan.model.AbstractPlanMatch;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductPlanTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

/**
 *  API渠道-平台计划分发
 *
 *  @author Pan
 */
@Service
public class ApiPlatformPhoneMd5Distribute implements PlanDistributeStrategy<ApiPlatformPhoneMd5ConvertHandler> {

    @Autowired
    private BaseDistribute baseDistribute;
    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private ProductPlanTypeService productPlanTypeService;

    @Override
    public PlanDistributeResult preValidate(PlanDistribute planDistribute) {
        //  基础校验
        PlanDistributeResult planDistributeResult = baseDistribute.preValidate(planDistribute);
        if (!planDistributeResult.getDistributeStatus()) {
            return planDistributeResult;
        }

        if (!baseDistribute.validExistMd5Filter(planDistribute)) {
            return PlanDistributeResult.ofFail(planDistribute, "排重包中已发现该用户");
        }
        return planDistributeResult;
    }

    @Override
    public PlanDistributeResult distribute(PlanDistribute planDistribute) {
        return baseDistribute.distribute(planDistribute);
    }

    @Override
    public PlanDistributeField parseResponse(PlanDistribute planDistribute, ApiHttpMessage apiHttpMessage, ApiPlatformPhoneMd5ConvertHandler handler) throws Exception {
        String reqId = planDistribute.getReqId();
        ProductPlanPO productPlanPO = planDistribute.getProductPlanPO();
        ProductApplyFlowPO currentDistributeFlow = planDistribute.getCurrentDistributeFlow();
        String responseBody = apiHttpMessage.getResponseBody();

        //  验证非空情况
        if (ValidParam.isEmpty(responseBody)) {
            throw new ParamParserException("解析失败-响应体返回空");
        }

        //  解析响应体
        RespPlatformPhoneMd5DataExchange resp = handler.respDataExchange(responseBody);
        if (ValidParam.isNull(resp)) {
            throw new ParamParserException("撞库参数异常:API平台-md5模式-未返回业务实体请检查");
        }

        //  验证返回业务消息是否成功
        if (!resp.getHasBizSuc()) {
            return PlanDistributeField.ofFail("API平台-md5模式-处理响应结果-对方返回结果[失败]", ProductApplyFlowStatusEnum.PLAT_FORM_DATA_EXCHANGE_FAIL);
        }

        //  验证参数
        boolean hasPlatShare = productPlanTypeService.hasPlatShare(productPlanPO);
        String errorMsg = baseDistribute.validRespPlatformByMd5(resp, hasPlatShare);
        if (ValidParam.isNotEmpty(errorMsg)) {
            throw new ParamParserException("撞库参数异常:API平台-md5模式-解析参数失败:" + errorMsg);
        }

        //  如果为空则设置我方平台中的logo地址
        if (ValidParam.isEmpty(resp.getLogoPath())) {
            resp.setLogoPath(productPlanPO.getLogoPath());
        }

        //  撞库流程http响应保存->序列化解析对象
        currentDistributeFlow.setRespData(JsonUtils.toJson(resp));

        //  构建返回字段
        return PlanDistributeField.ofPlatformPhoneMd5(resp, reqId);
    }

    @Override
    public PlanDistributeResult post(PlanDistributePost planDistributePost) {
        //  获取字段
        PlanDistributeField planDistributeField = planDistributePost.getPlanDistributeField();
        PlanDistributePhoneMd5Field phoneMd5Field = planDistributeField.getPhoneMd5Field();

        //  获取业务参数
        PlanDistribute planDistribute = planDistributePost.getPlanDistribute();
        ProductPO productPO = planDistribute.getProductPO();
        ProductPlanPO productPlanPO = planDistribute.getProductPlanPO();
        PlanDistributeUserRequest planDistributeUserRequest = planDistribute.getPlanDistributeUserRequest();

        //  获取原价
        AbstractPlanMatch abstractPlanMatch = planDistributePost.getAbstractPlanMatch();
        BigDecimal channelPrice = abstractPlanMatch.getChannelPrice();
        //  返回原价
        BigDecimal resultPrice = phoneMd5Field.getPrice();

        //  计算最终价格
        boolean hasPlatShare = productPlanTypeService.hasPlatShare(productPlanPO);
        BigDecimal finalPrice;
        //  分润模式
        if (hasPlatShare) {
            //  原价 * 渠道分成份额% = 分润后的单价
            BigDecimal percent = BigDecimalUtils.division(productPlanPO.getShare(), 100);
            finalPrice = BigDecimalUtils.multiply(resultPrice, percent).setScale(2, RoundingMode.DOWN);
        } else {
            finalPrice = productPlanPO.getPrice();
        }

        //  二次验证平台计划回传价格是否低于当前渠道价
        if (!apiBizRequiredService.requiredPlanPrice(finalPrice, channelPrice)) {
            PlanDistributeResult planDistributeResult = PlanDistributeResult.ofFail(planDistributePost);
            planDistributeResult.setBizErrorMsg("二次验证[单价]-无分发记录");
            planDistributeResult.setBizErrorType(ProductApplyFlowStatusEnum.PLAT_FORM_DATA_EXCHANGE_FAIL);
            return planDistributeResult;
        }

        //  保存进件单号流程标识
        String saveApplyId = phoneMd5Field.getApplyId();
        if (ValidParam.isNotEmpty(saveApplyId)) {
            String phoneMd5 = planDistributeUserRequest.getPhoneMd5();
            Map<String, String> saveMap = MapUtils.newLinkedHashMap(newMap -> {
                newMap.put("phoneMd5", phoneMd5);
                newMap.put("applyId", saveApplyId);
            });

            //  根据phoneMd5获取数据对象(我方接入下游-进件时根据phoneMd5获取本次applyId)
            String keyByPhoneMd5 = ApiMatchRedisKey.getDataExchangeUniqueIdByPhoneMd5(productPO.getId(), productPlanPO.getId(), phoneMd5);
            String saveValue = JsonUtils.toJson(saveMap);
            ApiMatchRedisKey.DOWNSTREAM_EXTEND.setForMinutes(keyByPhoneMd5, saveValue, 10);

            //  根据传递的applyId获取数据对象（我方接入下游-请求进件申请时根据applyId获取本次phoneMd5）
            String keyBySaveApplyId = ApiMatchRedisKey.getDataExchangeUniqueIdByApplyId(productPO.getId(), productPlanPO.getId(), saveApplyId);
            ApiMatchRedisKey.DOWNSTREAM_EXTEND.setForMinutes(keyBySaveApplyId, saveValue, 10);
        }

        //  修改返回属性
        phoneMd5Field.setPhoneMd5(planDistributeUserRequest.getPhoneMd5());
        phoneMd5Field.setPrice(finalPrice);
        return PlanDistributeResult.ofSuc(planDistributePost);
    }
}
